<template>
  <div class="dashboard-container">
    <!-- 顶部统计卡片区 -->
    <div class="card-row">
      <a-card v-for="card in cards" :key="card.key" :class="['stat-card', { active: selectedType === card.key, 'error-state': card.hasError }]"
        hoverable @click="selectType(card.key)">
        <div class="card-content">
          <div class="card-title">
            <component :is="card.icon" :class="['card-icon', { 'error-icon': card.hasError }]" />
            <span>{{ card.title }}</span>
          </div>
          <div class="card-value">{{ card.value }}</div>
          <div class="card-desc" :class="{ 'error-desc': card.hasError }">
            {{ card.desc }}
          </div>
        </div>
      </a-card>
    </div>
    <!-- 折线图区 -->
    <div class="chart-area">
      <div v-if="isLoading" class="loading-overlay">
        <a-spin size="large" />
        <div class="loading-text">数据加载中...</div>
      </div>
      <div ref="chartRef" class="chart-box" />
    </div>
    
    <!-- 页面级消息提示 -->
    <div class="dashboard-messages" v-if="dashboardMessages.length">
      <transition-group name="message-fade">
        <div v-for="msg in dashboardMessages" :key="msg.id" :class="['dashboard-message', `dashboard-message-${msg.type}`]">
          <span class="message-content">{{ msg.content }}</span>
        </div>
      </transition-group>
    </div>
  </div>
</template>

<script setup>
import { ref, reactive, onMounted, watch, nextTick, onUnmounted } from 'vue'
import * as echarts from 'echarts'
import { FundOutlined, DatabaseOutlined, HddOutlined, NodeIndexOutlined } from '@ant-design/icons-vue'
import { getCardSummary, getChartHistory } from '@/api/index.js'
import { message } from 'ant-design-vue'
// 移除 store 相关 import
// import { useDashboardStore } from '@/store/dashboard'

const errorNotifiedSet = new Set()

// 页面级消息管理
const dashboardMessages = ref([])
let messageIdCounter = 0

// 页面级消息系统
const showPageMessage = (content, type = 'info', duration = 3000) => {
  const id = messageIdCounter++
  const msg = { id, content, type }
  dashboardMessages.value.push(msg)
  
  // 自动移除消息
  setTimeout(() => {
    const index = dashboardMessages.value.findIndex(m => m.id === id)
    if (index !== -1) {
      dashboardMessages.value.splice(index, 1)
    }
  }, duration)
  
  return id
}

// 移除 store 相关内容，改为本地变量
const cards = reactive([
  {
    key: 'cpu',
    title: 'CPU',
    icon: FundOutlined,
    value: '0%',
    desc: '暂无数据',
    hasError: false
  },
  {
    key: 'memory',
    title: '内存',
    icon: DatabaseOutlined,
    value: '0%',
    desc: '暂无数据',
    hasError: false
  },
  {
    key: 'disk',
    title: '磁盘',
    icon: HddOutlined,
    value: '0%',
    desc: '暂无数据',
    hasError: false
  },
  {
    key: 'network',
    title: '网络',
    icon: NodeIndexOutlined,
    value: '0%',
    desc: '暂无数据',
    hasError: false
  }
])

const chartDataMap = reactive({
  cpu: { x: [], y: [], title: 'CPU使用率', unit: '%', hasError: false },
  memory: { x: [], y: [], title: '内存使用率', unit: '%', hasError: false },
  disk: { x: [], read: [], write: [], title: '磁盘读写速率', unit: 'MB/s', hasError: false },
  network: { x: [], y: [], title: '网络流量', unit: 'KB/s', hasError: false }
})

const selectedType = ref('cpu')
const chartRef = ref(null)
let chartInstance = null
const isLoading = ref(false)

// 滑动窗口配置
const MAX_DATA_POINTS = 20

const typeColorMap = {
  cpu: '#1677ff',
  memory: '#52c41a',
  disk: '#faad14',
  network: '#722ed1'
}

// 定时器
let cardUpdateTimer = null
let chartUpdateTimer = null
let resizeObserver = null

// 更新单个卡片数据
async function updateSingleCardData(card) {
  try {
    const summary = await getCardSummary(card.key)
    if (summary && summary.value !== undefined) {
      card.value = summary.value
      card.desc = summary.desc
      card.hasError = false
      errorNotifiedSet.delete(card.key)
    } else {
      throw new Error('无数据')
    }
  } catch (error) {
    if (!card.hasError) {
      card.hasError = true
      card.desc = '数据获取失败'
      if (!errorNotifiedSet.has(card.key)) {
        showPageMessage(`${card.title}数据获取失败`, 'error')
        errorNotifiedSet.add(card.key)
      }
    }
  }
}

// 更新卡片数据
async function updateCardData() {
  await Promise.all(cards.map(card => updateSingleCardData(card)))
}

// 更新折线图数据
async function updateChartData() {
  const currentType = selectedType.value
  const chartData = chartDataMap[currentType]
  try {
    const historyData = await getChartHistory(currentType)
    if (currentType === 'disk' && historyData && Array.isArray(historyData.x) && Array.isArray(historyData.read) && Array.isArray(historyData.write)) {
      chartDataMap.disk = {
        ...chartDataMap.disk,
        x: historyData.x,
        read: historyData.read,
        write: historyData.write,
        title: historyData.title,
        unit: historyData.unit,
        hasError: false
      }
    } else if (historyData && Array.isArray(historyData.x) && Array.isArray(historyData.y)) {
      chartDataMap[currentType] = {
        ...chartDataMap[currentType],
        x: historyData.x,
        y: historyData.y,
        title: historyData.title,
        unit: historyData.unit,
        hasError: false
      }
    } else {
      throw new Error('数据结构异常')
    }
    chartData.hasError = false
    renderChart()
  } catch (error) {
    chartData.hasError = true
    if (!errorNotifiedSet.has(currentType)) {
      showPageMessage(`${chartData.title}数据获取失败`, 'error')
      errorNotifiedSet.add(currentType)
    }
  }
}

const renderChart = () => {
  const currentData = chartDataMap[selectedType.value]
  if (!chartInstance) {
    chartInstance = echarts.init(chartRef.value, null, { renderer: 'canvas' })
  }
  
  // 如果数据为空或加载中，显示加载状态
  if (!currentData || currentData.x.length === 0) {
    const option = {
      title: { 
        text: '数据加载中...', 
        left: 'center', 
        top: 'center',
        textStyle: { fontSize: 16, color: '#999' }
      },
      graphic: {
        type: 'text',
        left: 'center',
        top: '60%',
        style: {
          text: '请稍候...',
          fontSize: 14,
          fill: '#999'
        }
      }
    }
    chartInstance.setOption(option)
    return
  }
  
  if (selectedType.value === 'disk') {
    if (!currentData.read || !currentData.write) {
      const option = {
        title: { 
          text: '磁盘数据加载中...', 
          left: 'center', 
          top: 'center',
          textStyle: { fontSize: 16, color: '#999' }
        }
      }
      chartInstance.setOption(option)
      return
    }
    const minValue = Math.min(...currentData.read, ...currentData.write)
    const maxValue = Math.max(...currentData.read, ...currentData.write)
    const padding = (maxValue - minValue) * 0.1 || 10
    const option = {
      title: { 
        text: currentData.title, 
        left: 'center', 
        top: 10, 
        textStyle: { fontSize: 18, fontWeight: 'bold' } 
      },
      tooltip: { 
        trigger: 'axis',
        formatter: function(params) {
          let result = params[0].axisValueLabel + '<br/>';
          params.forEach(param => {
            // 添加彩色标记和数值
            result += `<span style="display:inline-block;margin-right:4px;border-radius:50%;width:10px;height:10px;background-color:${param.color};"></span>`;
            result += `${param.seriesName}: <strong>${param.value}</strong>${currentData.unit}<br/>`;
          });
          return result;
        },
        axisPointer: {
          type: 'line',
          lineStyle: {
            color: 'rgba(0,0,0,0.2)',
            width: 1,
            type: 'solid'
          }
        }
      },
      legend: {
        data: ['读取速度', '写入速度'],
        top: 40,
        textStyle: {
          fontSize: 12
        }
      },
      grid: { 
        left: '3%', 
        right: '4%', 
        bottom: '3%', 
        top: 70, 
        containLabel: true 
      },
      xAxis: { 
        type: 'category', 
        data: currentData.x, 
        boundaryGap: false, 
        axisLabel: { 
          rotate: 45, 
          fontSize: 10,
          interval: 'auto',
          hideOverlap: true,
          formatter: function(value) {
            // 如果是时间戳格式，只保留时分秒
            if (value.includes(':')) {
              return value.split(' ').pop();
            }
            return value;
          }
        },
        axisLine: {
          lineStyle: {
            color: '#ddd'
          }
        },
        axisTick: {
          alignWithLabel: true
        }
      },
      yAxis: { 
        type: 'value', 
        min: minValue - padding < 0 ? 0 : minValue - padding, 
        max: maxValue + padding, 
        axisLabel: { 
          formatter: function(value) {
            // 控制小数位数，最多显示2位小数
            if (Number.isInteger(value)) {
              return value + currentData.unit;
            } else {
              return value.toFixed(2) + currentData.unit;
            }
          },
          fontSize: 12
        },
        splitLine: {
          lineStyle: {
            color: '#eee',
            type: 'dashed'
          }
        }
      },
      series: [
        {
          name: '读取速度',
          data: currentData.read,
          type: 'line',
          smooth: true,
          areaStyle: { 
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: 'rgba(22, 119, 255, 0.5)' },
              { offset: 1, color: 'rgba(22, 119, 255, 0.1)' }
            ])
          },
          lineStyle: { color: '#1677ff', width: 2 },
          symbol: 'circle',
          symbolSize: 6,
          itemStyle: { color: '#1677ff' }
        },
        {
          name: '写入速度',
          data: currentData.write,
          type: 'line',
          smooth: true,
          areaStyle: { 
            color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
              { offset: 0, color: 'rgba(250, 173, 20, 0.5)' },
              { offset: 1, color: 'rgba(250, 173, 20, 0.1)' }
            ])
          },
          lineStyle: { color: '#faad14', width: 2 },
          symbol: 'circle',
          symbolSize: 6,
          itemStyle: { color: '#faad14' }
        }
      ],
      responsive: true,
      maintainAspectRatio: false
    }
    chartInstance.setOption(option, true)
    return
  }
  // 其他类型单曲线
  if (currentData.y.length === 0) {
    const option = {
      title: { 
        text: `${currentData.title}数据加载中...`, 
        left: 'center', 
        top: 'center',
        textStyle: { fontSize: 16, color: '#999' }
      }
    }
    chartInstance.setOption(option)
    return
  }
  const minValue = Math.min(...currentData.y)
  const maxValue = Math.max(...currentData.y)
  const padding = (maxValue - minValue) * 0.1 || 10
  const option = {
    title: { 
      text: currentData.title, 
      left: 'center', 
      top: 10, 
      textStyle: { fontSize: 18, fontWeight: 'bold' } 
    },
    tooltip: { 
      trigger: 'axis',
      formatter: function(params) {
        const param = params[0];
        return param.axisValueLabel + '<br/>' + 
               `<span style="display:inline-block;margin-right:4px;border-radius:50%;width:10px;height:10px;background-color:${param.color};"></span>` +
               `${param.seriesName}: <strong>${param.value}</strong>${currentData.unit}`;
      },
      axisPointer: {
        type: 'line',
        lineStyle: {
          color: 'rgba(0,0,0,0.2)',
          width: 1,
          type: 'solid'
        }
      }
    },
    grid: { 
      left: '3%', 
      right: '4%', 
      bottom: '3%', 
      top: 60, 
      containLabel: true 
    },
    xAxis: { 
      type: 'category', 
      data: currentData.x, 
      boundaryGap: false, 
      axisLabel: { 
        rotate: 45, 
        fontSize: 10,
        interval: 'auto',
        hideOverlap: true,
        formatter: function(value) {
          // 如果是时间戳格式，只保留时分秒
          if (value.includes(':')) {
            return value.split(' ').pop();
          }
          return value;
        }
      },
      axisLine: {
        lineStyle: {
          color: '#ddd'
        }
      },
      axisTick: {
        alignWithLabel: true
      }
    },
    yAxis: { 
      type: 'value', 
      min: minValue - padding < 0 ? 0 : minValue - padding, 
      max: maxValue + padding, 
      axisLabel: { 
        formatter: function(value) {
          // 控制小数位数，最多显示2位小数
          if (Number.isInteger(value)) {
            return value + currentData.unit;
          } else {
            return value.toFixed(2) + currentData.unit;
          }
        },
        fontSize: 12
      },
      splitLine: {
        lineStyle: {
          color: '#eee',
          type: 'dashed'
        }
      }
    },
    series: [
      {
        name: currentData.title,
        data: currentData.y,
        type: 'line',
        smooth: true,
        areaStyle: { 
          color: new echarts.graphic.LinearGradient(0, 0, 0, 1, [
            { offset: 0, color: typeColorMap[selectedType.value] + '80' },
            { offset: 1, color: typeColorMap[selectedType.value] + '10' }
          ])
        },
        lineStyle: { color: typeColorMap[selectedType.value], width: 2 },
        symbol: 'circle',
        symbolSize: 6,
        itemStyle: { color: typeColorMap[selectedType.value] },
      },
    ],
    responsive: true,
    maintainAspectRatio: false
  }
  chartInstance.setOption(option, true)
}

// 处理窗口大小变化
const handleResize = () => {
  if (chartInstance) {
    chartInstance.resize()
  }
}

const selectType = async (type) => {
  selectedType.value = type
  
  // 如果当前类型的数据为空或有过错，立即加载数据
  const chartData = chartDataMap[type]
  if (!chartData || chartData.x.length === 0 || chartData.hasError) {
    isLoading.value = true
    try {
      await updateChartData()
    } finally {
      isLoading.value = false
    }
  } else {
    // 如果数据已存在，直接渲染
    renderChart()
  }
}

// 重置错误状态（手动重试）
const resetErrorState = (type) => {
  const card = cards.find(c => c.key === type)
  if (card) {
    card.hasError = false
    card.desc = '重新加载中...'
    errorNotifiedSet.delete(card.key)
  }
  const chartData = chartDataMap[type]
  if (chartData) {
    chartData.hasError = false
  }
  if (card) {
    updateSingleCardData(card)
  }
  if (chartData && selectedType.value === type) {
    updateChartData()
  }
}

// 预加载所有类型的图表数据
async function preloadAllChartData() {
  const types = ['cpu', 'memory', 'disk', 'network']
  await Promise.all(types.map(async (type) => {
    const chartData = chartDataMap[type]
    if (!chartData || chartData.x.length === 0) {
      try {
        const historyData = await getChartHistory(type)
        if (type === 'disk' && historyData && Array.isArray(historyData.x) && Array.isArray(historyData.read) && Array.isArray(historyData.write)) {
          chartDataMap.disk = {
            ...chartDataMap.disk,
            x: historyData.x,
            read: historyData.read,
            write: historyData.write,
            title: historyData.title,
            unit: historyData.unit,
            hasError: false
          }
        } else if (historyData && Array.isArray(historyData.x) && Array.isArray(historyData.y)) {
          chartDataMap[type] = {
            ...chartDataMap[type],
            x: historyData.x,
            y: historyData.y,
            title: historyData.title,
            unit: historyData.unit,
            hasError: false
          }
        }
      } catch (error) {
        chartDataMap[type].hasError = true
        console.error(`${type}数据预加载失败:`, error)
      }
    }
  }))
}

// 启动定时更新
async function startTimers() {
  // 卡片数据每5秒更新一次
  cardUpdateTimer = setInterval(updateCardData, 3000)
  // 折线图数据每10秒更新一次
  chartUpdateTimer = setInterval(updateChartData, 3000)
  // 立即执行一次
  await updateCardData()
  await preloadAllChartData() // 预加载所有图表数据
  await updateChartData() // 更新当前选中类型的数据
}

// 停止定时更新
function stopTimers() {
  if (cardUpdateTimer) {
    clearInterval(cardUpdateTimer)
    cardUpdateTimer = null
  }
  if (chartUpdateTimer) {
    clearInterval(chartUpdateTimer)
    chartUpdateTimer = null
  }
}

// 设置图表容器大小
const setupChartResizeObserver = () => {
  if (chartRef.value) {
    // 使用ResizeObserver监听容器大小变化
    resizeObserver = new ResizeObserver(() => {
      handleResize()
    })
    resizeObserver.observe(chartRef.value)
  }
  // 同时监听窗口大小变化
  window.addEventListener('resize', handleResize)
}

onMounted(() => {
  startTimers()
  nextTick(() => {
    setupChartResizeObserver()
  })
})

onUnmounted(() => {
  stopTimers()
  if (chartInstance) {
    chartInstance.dispose()
    chartInstance = null
  }
  if (resizeObserver) {
    resizeObserver.disconnect()
    resizeObserver = null
  }
  window.removeEventListener('resize', handleResize)
})
</script>

<style scoped>
.dashboard-container {
  display: flex;
  flex-direction: column;
  gap: 20px;
  padding: 10px;
  width: 100%;
  max-width: 100%;
  box-sizing: border-box;
  overflow-x: hidden;
}

.card-row {
  display: flex;
  flex-wrap: wrap;
  gap: 16px;
  margin-bottom: 15px;
  width: 100%;
}

.stat-card {
  flex: 1 1 200px;
  cursor: pointer;
  border: 2px solid #f0f1f2;
  transition: border-color 0.2s, box-shadow 0.2s;
  min-width: 150px;
  min-height: 100px;
  box-shadow: 0 2px 8px #f0f1f2;
  border-radius: 10px;
  background: #fafcff;
  margin-bottom: 10px;
}

.stat-card.active {
  border-color: #1677ff;
  box-shadow: 0 4px 16px #e6f7ff;
}

.stat-card.error-state {
  border-color: #ff4d4f;
  box-shadow: 0 4px 16px #fff2f0;
  background: #fff2f0;
}

.stat-card.error-state.active {
  border-color: #ff4d4f;
  box-shadow: 0 4px 16px #fff2f0;
}

.card-content {
  display: flex;
  flex-direction: column;
  gap: 6px;
}

.card-title {
  display: flex;
  align-items: center;
  gap: 8px;
  font-size: 16px;
  font-weight: 500;
}

.card-icon {
  font-size: 22px;
  color: #1677ff;
}

.card-icon.error-icon {
  color: #ff4d4f;
}

.card-value {
  font-size: 24px;
  font-weight: bold;
  color: #222;
}

.card-desc {
  font-size: 13px;
  color: #888;
}

.card-desc.error-desc {
  color: #ff4d4f;
  font-weight: 500;
}

.chart-area {
  width: 100%;
  height: calc(100vh - 280px);
  min-height: 300px;
  background: #fff;
  border-radius: 14px;
  box-shadow: 0 2px 12px #f0f1f2;
  padding: 16px;
  display: flex;
  align-items: center;
  justify-content: center;
  position: relative;
  overflow: hidden;
}

.chart-box {
  width: 100%;
  height: 100%;
  min-height: 280px;
}

.loading-overlay {
  position: absolute;
  top: 0;
  left: 0;
  right: 0;
  bottom: 0;
  background: rgba(255, 255, 255, 0.9);
  display: flex;
  flex-direction: column;
  align-items: center;
  justify-content: center;
  z-index: 10;
  border-radius: 10px;
}

.loading-text {
  margin-top: 16px;
  color: #666;
  font-size: 14px;
}

/* 响应式布局 */
@media (max-width: 768px) {
  .card-row {
    flex-direction: column;
  }
  
  .stat-card {
    flex: 1 1 100%;
    min-height: 90px;
  }
  
  .card-value {
    font-size: 22px;
  }
  
  .chart-area {
    height: calc(100vh - 350px);
    min-height: 250px;
    padding: 12px;
  }
}

@media (max-width: 480px) {
  .dashboard-container {
    gap: 15px;
    padding: 8px;
  }
  
  .card-row {
    gap: 12px;
    margin-bottom: 10px;
  }
  
  .stat-card {
    min-height: 80px;
  }
  
  .card-title {
    font-size: 14px;
  }
  
  .card-icon {
    font-size: 18px;
  }
  
  .card-value {
    font-size: 20px;
  }
  
  .card-desc {
    font-size: 12px;
  }
  
  .chart-area {
    height: calc(100vh - 320px);
    min-height: 220px;
    padding: 10px;
  }
}

/* 页面级消息样式 */
.dashboard-messages {
  position: fixed;
  top: 16px;
  right: 16px;
  z-index: 1000;
  display: flex;
  flex-direction: column;
  gap: 8px;
}

.dashboard-message {
  padding: 8px 16px;
  border-radius: 4px;
  box-shadow: 0 2px 8px rgba(0, 0, 0, 0.15);
  animation: slide-in 0.3s ease;
  min-width: 200px;
}

.dashboard-message-info {
  background-color: #e6f7ff;
  border: 1px solid #91d5ff;
}

.dashboard-message-success {
  background-color: #f6ffed;
  border: 1px solid #b7eb8f;
}

.dashboard-message-warning {
  background-color: #fffbe6;
  border: 1px solid #ffe58f;
}

.dashboard-message-error {
  background-color: #fff2f0;
  border: 1px solid #ffccc7;
}

.message-fade-enter-active,
.message-fade-leave-active {
  transition: opacity 0.3s, transform 0.3s;
}

.message-fade-enter-from,
.message-fade-leave-to {
  opacity: 0;
  transform: translateX(30px);
}

@keyframes slide-in {
  from {
    transform: translateX(30px);
    opacity: 0;
  }
  to {
    transform: translateX(0);
    opacity: 1;
  }
}
</style>